package com.pww.movie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.pww.movie.domain.DTO.UserLikeDTO;
import com.pww.movie.domain.PO.Media;
import com.pww.movie.domain.PO.UserLike;
import com.pww.movie.mapper.MediaMapper;
import com.pww.movie.mapper.UserLikeMapper;
import com.pww.movie.service.IUserLikeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pww.movie.utils.ThreadLocalUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author pww
 * @since 2025-06-13
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class UserLikeServiceImpl extends ServiceImpl<UserLikeMapper, UserLike> implements IUserLikeService {
    private final UserLikeMapper userLikeMapper;
    private final MediaMapper mediaMapper;
    private final RedisTemplate<String, String> redisTemplate;


    @Override
    public Boolean like(UserLikeDTO userLikeDTO) {
        //获取用户id
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get("id");
        //判断userLikeDTO是否为空
        if (userLikeDTO == null) {
            return false;
        }

        //判断userId是否为空
        if (userId == null) {
            return false;
        }
        //写入数据库
        UserLike userLike = new UserLike()
                .setUserId(Long.valueOf(userId))
                .setMediaId(Long.valueOf(userLikeDTO.getMediaId()))
                .setMediaType(userLikeDTO.getMediaType());
        int insert = userLikeMapper.insert(userLike);
        //如果插入成功，更新Redis缓存
        if (insert > 0) {
            String userLikeKey = getUserLikeKey(Long.valueOf(userId));
            String mediaKey = userLike.getMediaType() + ":" + userLike.getMediaId();
            redisTemplate.opsForSet().add(userLikeKey, mediaKey);
        }
        return true;
    }

    @Override
    public Boolean unlike(UserLikeDTO userLikeDTO) {
        //获取用户id
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get("id");
        String userLikeKey = getUserLikeKey(Long.valueOf(userId));
        String mediaKey = userLikeDTO.getMediaType() + ":" + userLikeDTO.getMediaId();
        //判断userLikeDTO是否为空
        if (userLikeDTO == null) {
            return false;
        }
        //判断用户id'是否为空
        if (userId == null) {
            return false;
        }
        //删除数据库中的记录
        int isDelete = userLikeMapper.delete(new LambdaQueryWrapper<UserLike>()
                .eq(UserLike::getUserId, userId).eq(UserLike::getMediaId, userLikeDTO.getMediaId())
                .eq(UserLike::getMediaType, userLikeDTO.getMediaType()));
        //如果删除成功，更新Redis缓存
        if (isDelete > 0) {
            redisTemplate.opsForSet().remove(userLikeKey, mediaKey);
        }

        return true;
    }

    @Override
    public List<Media> getUserLikedMedia(String mediaType) {
        //获取用户id
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get("id");
        //获取key
        String userLikeKey = getUserLikeKey(Long.valueOf(userId));
        //获取缓存
        Set<String> likes = redisTemplate.opsForSet().members(userLikeKey);
        log.info("likes:{}", likes);
        //如果缓存不为空，则返回缓存
        if (likes == null || likes.isEmpty()) return Collections.emptyList();
        //获取制定类型的媒体数据
        List<Long> mediaIds = likes.stream()
                .filter(like -> like.startsWith(mediaType + ":"))
                .map(like -> Long.parseLong(like.split(":")[1]))
                .collect(Collectors.toList());
        log.info("mediaIds:{}", mediaIds);
        //如果mediaIds为空，则返回空列表
        if (mediaIds.isEmpty()) return Collections.emptyList();
        //如果mediaIds不是空查询数据库
        return mediaMapper.selectByIds(mediaIds);
    }

    private String getUserLikeKey(Long userId) {
        return "like:user:" + userId;
    }
}
